package cn.net.xyan.kotlin

import com.fasterxml.jackson.databind.ObjectMapper
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
import kotlin.reflect.full.memberProperties


/**
 * Created by zarra on 2017/3/22.
 */

@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class NoArg

class LoggerPropertyDelegate<in T : Any> : ReadOnlyProperty<T, Logger> {

    operator override fun getValue(thisRef: T, property: KProperty<*>): Logger {
        val logger = LoggerFactory.getLogger(thisRef.javaClass)
        return logger
    }

}

val <T : Any> T.logger: Logger by LoggerPropertyDelegate()


fun <T : Any> T.getKProperties(): Collection<KProperty<*>> {
    return this::class.memberProperties
}

fun <T : Any> T.getKProperty(propertyName: String): KProperty<*> {
    return getKProperties().filter {
        it.name == propertyName
    }.first()
}


typealias PairList<T, V> = List<Pair<T, V>>

fun <T : Any> T.getProperties(): PairList<String, String> {
    val om = ObjectMapper()
    val json = om.writeValueAsString(this)

    val mapType = om.typeFactory.constructMapType(Map::class.java, String::class.java, String::class.java)

    val map: Map<String, String> = om.readValue(json, mapType)

    val pairList: PairList<String, String> = map.map {
        Pair(it.key, it.value)
    }.toList()

    return pairList
}
